package com.vimi8.chick.plugins.adapter

import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.support.v4.app.FragmentManager
import android.support.v4.content.ContextCompat
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import cn.qqtheme.framework.picker.DatePicker
import cn.qqtheme.framework.picker.DateTimePicker
import cn.qqtheme.framework.picker.TimePicker
import com.afollestad.materialdialogs.GravityEnum
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.Theme
import com.eros.framework.manager.ManagerFactory
import com.eros.framework.manager.impl.ParseManager
import com.taobao.weex.bridge.JSCallback
import com.vimi8.chick.plugins.R
import com.vimi8.chick.plugins.model.DatePickerBean
import com.vimi8.chick.plugins.model.DateRangeBean
import com.vimi8.chick.plugins.model.DialogBean
import com.vimi8.chick.plugins.utils.DateTimeUtil
import com.vimi8.chick.plugins.widgets.dialogs.DateRangeSelectDialog
import java.util.*

object DialogAdapter {
    fun show(params: String, context: Context, jsPositive: JSCallback?, jsNegative: JSCallback?, jsNeutral: JSCallback?, jsDismiss: JSCallback?) {
        val bean = ManagerFactory.getManagerService(ParseManager::class.java).parseObject(params, DialogBean::class.java)
        val dialogBuilder = dialogBuild(context, bean, jsDismiss)
        if (!bean.positiveText.isNullOrEmpty()) {
            dialogBuilder.positiveText(bean.positiveText!!)
        }
        if (!bean.negativeText.isNullOrEmpty()) {
            dialogBuilder.negativeText(bean.negativeText!!)
        }
        if (!bean.neutralText.isNullOrEmpty()) {
            dialogBuilder.neutralText(bean.neutralText!!)
        }
        dialogBuilder.onPositive { _, which -> jsPositive?.invoke(which) }
        dialogBuilder.onNegative { _, which -> jsNegative?.invoke(which) }
        dialogBuilder.onNeutral { _, which -> jsNeutral?.invoke(which) }

        dialogBuilder.customView(R.layout.dialog_customer_view, true)

        val mDialog = dialogBuilder.build()
        val mView = mDialog.customView

        // title
        val mTitleFrame = mView?.findViewById(R.id.mTitleFrame) as LinearLayout
        val mTitle = mView.findViewById<TextView>(R.id.mTitle)
        mTitle?.gravity = getGravity(bean.titleGravity ?: "start").gravityInt
        if (bean.title.isNullOrEmpty()) {
            mTitleFrame.visibility = View.GONE
        } else {
            mTitleFrame.visibility = View.VISIBLE
            mTitle?.text = bean.title
        }

        // icon
        //        val mIcon = mView.findViewById<ImageView>(R.id.mIcon)
        //        when {
        //            bean.icon.isEmpty() -> mIcon?.visibility = View.GONE
        //            else -> {
        //                val iconDrawable = FileUtil.assets2Drawable(context, getAssetsPath(context, bean.icon))
        //                when {
        //                    iconDrawable != null -> {
        //                        mIcon?.visibility = View.VISIBLE
        //                        mIcon?.setImageDrawable(iconDrawable)
        //                    }
        //                    else -> mIcon?.visibility = View.GONE
        //                }
        //            }
        //        }

        // content
        val mContent = mView.findViewById<TextView>(R.id.mContent)
        mContent?.gravity = getGravity(bean.contentGravity ?: "start").gravityInt
        if (bean.content.isNullOrEmpty()) {
            mContent.visibility = View.GONE
        } else {
            mContent.visibility = View.VISIBLE
            mContent?.text = bean.content
        }

        mDialog.show()
    }

    fun list(params: String, context: Context, jsPositive: JSCallback?, jsDismiss: JSCallback?) {
        val bean = ManagerFactory.getManagerService(ParseManager::class.java).parseObject(params, DialogBean::class.java)
        val dialogBuilder = dialogBuild(context, bean, jsDismiss)
        if (bean.items.isNullOrEmpty()) {
            return
        }

        if (!bean.title.isNullOrEmpty()) {
            dialogBuilder.title(bean.title!!)
        }
        dialogBuilder
            .items(bean.items!!)
            .itemsCallback { _, _, position, text ->
                jsPositive?.invoke(hashMapOf(
                    "position" to position,
                    "text" to text
                ))
            }
            .show()
    }

    fun radio(params: String, context: Context, jsPositive: JSCallback?, jsNegative: JSCallback?, jsDismiss: JSCallback?) {
        val bean = ManagerFactory.getManagerService(ParseManager::class.java).parseObject(params, DialogBean::class.java)
        var mPosition = bean.selectedIndex ?: -1
        var mText = ""
        val dialogBuilder = dialogBuild(context, bean, jsDismiss)
        if (bean.items.isNullOrEmpty()) {
            return
        }

        if (!bean.title.isNullOrEmpty()) {
            dialogBuilder.title(bean.title!!)
        }
        if (!bean.positiveText.isNullOrEmpty()) {
            dialogBuilder.positiveText(bean.positiveText!!)
        }
        if (!bean.negativeText.isNullOrEmpty()) {
            dialogBuilder.negativeText(bean.negativeText!!)
        }
        dialogBuilder.onPositive { _, _ ->
            jsPositive?.invoke(hashMapOf(
                "position" to mPosition,
                "text" to mText
            ))
        }
        dialogBuilder.onNegative { _, which -> jsNegative?.invoke(which) }
        dialogBuilder.items(bean.items!!)
            .itemsCallbackSingleChoice(bean.selectedIndex
                ?: -1) { _, _, which, text ->
                mPosition = which
                mText = text.toString()
                true
            }
            .show()
    }

    fun select(params: String, context: Context, jsPositive: JSCallback?, jsNegative: JSCallback?, jsDismiss: JSCallback?) {
        val bean = ManagerFactory.getManagerService(ParseManager::class.java).parseObject(params, DialogBean::class.java)
        var mPosition = bean.selectedArray
        var mText = listOf<String>()
        val dialogBuilder = dialogBuild(context, bean, jsDismiss)
        if (bean.items.isNullOrEmpty()) {
            return
        }

        if (!bean.title.isNullOrEmpty()) {
            dialogBuilder.title(bean.title!!)
        }
        if (!bean.positiveText.isNullOrEmpty()) {
            dialogBuilder.positiveText(bean.positiveText!!)
        }
        if (!bean.negativeText.isNullOrEmpty()) {
            dialogBuilder.negativeText(bean.negativeText!!)
        }
        dialogBuilder.onPositive { _, _ ->
            jsPositive?.invoke(hashMapOf(
                "position" to mPosition,
                "text" to mText
            ))
        }
        dialogBuilder.onNegative { _, which -> jsNegative?.invoke(which) }
        dialogBuilder.items(bean.items!!)
            .itemsCallbackMultiChoice(bean.selectedArray, object : MaterialDialog.ListCallbackMultiChoice {
                override fun onSelection(dialog: MaterialDialog?, which: Array<out Int>?, text: Array<out CharSequence>?): Boolean {
                    mPosition = which
                    mText = text?.map { it.toString() } ?: listOf()
                    return true
                }
            })
            .show()
    }

    fun dateRange(params: String, fm: FragmentManager, jsPositive: JSCallback?, jsDismiss: JSCallback?, jsReset: JSCallback?) {
        val bean = ManagerFactory.getManagerService(ParseManager::class.java).parseObject(params, DateRangeBean::class.java)
        val dialog = DateRangeSelectDialog.newInstance()

        val bundle = Bundle()
        bundle.putString(DateRangeSelectDialog.START_TIME, bean.start)
        bundle.putString(DateRangeSelectDialog.END_TIME, bean.end)
        bundle.putInt(DateRangeSelectDialog.START_DELTA, bean.startDelta)
        bundle.putInt(DateRangeSelectDialog.END_DELTA, bean.endDelta)
        dialog.arguments = bundle

        dialog.setShortcutButtonVisible(bean.shortcut)

        dialog.setOnDateRangeSelectListener(object : DateRangeSelectDialog.OnDateRangeSelectListener {
            override fun onSelect(ys: Int, ms: Int, ds: Int, ye: Int, me: Int, de: Int) {
                jsPositive?.invoke(hashMapOf(
                    "ys" to ys,
                    "ms" to ms,
                    "ds" to ds,
                    "ye" to ye,
                    "me" to me,
                    "de" to de
                ))
            }

            override fun onDismiss() {
                jsDismiss?.invoke(null)
            }

            override fun onReset() {
                jsReset?.invoke(null)
            }

        })

        dialog.show(fm, "DateRangeDialog")
    }

    private fun dialogBuild(context: Context, bean: DialogBean, jsDismiss: JSCallback?): MaterialDialog.Builder {
        val dialogBuilder = MaterialDialog.Builder(context)

        dialogBuilder.dismissListener { jsDismiss?.invoke(null) }

        dialogBuilder.theme(if (bean.theme == "dark") Theme.DARK else Theme.LIGHT)
        dialogBuilder.canceledOnTouchOutside(bean.cancelOnTouchOutside ?: true)
        dialogBuilder.cancelable(bean.cancelable ?: true)

        dialogBuilder.btnStackedGravity(getGravity(bean.btnStackedGravity ?: "start"))
        dialogBuilder.buttonsGravity(getGravity(bean.buttonsGravity ?: "start"))
        return dialogBuilder
    }

    private fun getGravity(gravity: String): GravityEnum {
        return when (gravity) {
            "end" -> GravityEnum.END
            "center" -> GravityEnum.CENTER
            else -> GravityEnum.START
        }
    }

    fun datePick(params: String, activity: Activity, jsPositive: JSCallback?, jsDismiss: JSCallback?) {
        val bean = ManagerFactory.getManagerService(ParseManager::class.java).parseObject(params, DatePickerBean::class.java)

        val nowCalendar = Calendar.getInstance()
        val pickType = bean.type

        if (pickType == 3) {
            if (bean.initialDate != null) {
                nowCalendar.time = DateTimeUtil.parseDate(bean.initialDate!!, DateTimeUtil.DF_HH_MM)
            }

            val timePicker = TimePicker(activity)
            timePicker.setTopLineVisible(false)
            timePicker.setSelectedItem(
                nowCalendar.get(Calendar.HOUR),
                nowCalendar.get(Calendar.MINUTE)
            )
            timePicker.setOnTimePickListener { hour, minute ->
                jsPositive?.invoke(hashMapOf("hour" to hour, "minute" to minute))
            }
            timePicker.show()

            return
        }

        var mode = DateTimePicker.YEAR_MONTH_DAY
        when (pickType) {
            0 -> {
                mode = DateTimePicker.YEAR_MONTH_DAY
            }
            1 -> {
                mode = DateTimePicker.YEAR_MONTH
            }
            2 -> {
                mode = DateTimePicker.MONTH_DAY
            }
        }

        val ft = DateTimeUtil.DF_YYYY_MM_DD

        // 选中的时间
        bean.initialDate?.let {
            nowCalendar.time = DateTimeUtil.parseDate(it, ft)
        }

        // 开始时间
        val startCalendar = Calendar.getInstance()
        bean.start?.let {
            startCalendar.time = DateTimeUtil.parseDate(it, ft)
        } ?: startCalendar.add(Calendar.YEAR, -30)

        // 结束时间
        val endCalendar = Calendar.getInstance()
        bean.end?.let {
            endCalendar.time = DateTimeUtil.parseDate(it, ft)
        } ?: endCalendar.add(Calendar.YEAR, 30)

        val datePicker = DatePicker(activity, mode)
        datePicker.setRangeStart(
            startCalendar.get(Calendar.YEAR),
            startCalendar.get(Calendar.MONTH) + 1,
            startCalendar.get(Calendar.DATE)
        )
        datePicker.setRangeEnd(
            endCalendar.get(Calendar.YEAR),
            endCalendar.get(Calendar.MONTH) + 1,
            endCalendar.get(Calendar.DATE)
        )

        datePicker.setTextColor(ContextCompat.getColor(activity, R.color.common_color_primary))
        datePicker.setOffset(bean.offset)
        datePicker.setLineSpaceMultiplier(bean.lineSpace)

        when (pickType) {
            0 -> {
                datePicker.setSelectedItem(
                    nowCalendar.get(Calendar.YEAR),
                    nowCalendar.get(Calendar.MONTH) + 1,
                    nowCalendar.get(Calendar.DATE)
                )
                datePicker.setOnDatePickListener(object : DatePicker.OnYearMonthDayPickListener {
                    override fun onDatePicked(year: String?, month: String?, day: String?) {
                        jsPositive?.invoke(hashMapOf(
                            "year" to year,
                            "month" to month,
                            "day" to day
                        ))
                    }
                })
            }
            1 -> {
                datePicker.setSelectedItem(
                    nowCalendar.get(Calendar.YEAR),
                    nowCalendar.get(Calendar.MONTH) + 1
                )
                datePicker.setOnDatePickListener(object : DatePicker.OnYearMonthPickListener {
                    override fun onDatePicked(year: String?, month: String?) {
                        jsPositive?.invoke(hashMapOf(
                            "year" to year,
                            "month" to month
                        ))
                    }
                })
            }
            2 -> {
                datePicker.setSelectedItem(
                    nowCalendar.get(Calendar.MONTH) + 1,
                    nowCalendar.get(Calendar.DATE)
                )
                datePicker.setOnDatePickListener(object : DatePicker.OnMonthDayPickListener {
                    override fun onDatePicked(month: String?, day: String?) {
                        jsPositive?.invoke(hashMapOf(
                            "month" to month,
                            "day" to day
                        ))
                    }
                })
            }
        }
        datePicker.setOnDismissListener { jsDismiss?.invoke(null) }

        datePicker.show()
    }

}
